1.3-运算符
Create by fall on 14 Sep 2021 Recently revised in 27 Jun 2023
算术运算符
和其他语言一样,所以我这里只是列出来
+
对数字进行求和,或者是拼接字符串-
对数字取负值,或者进行相减*
乘法运算/
除法运算%
取余运算
一些特殊的运算符
**
表示次方运算
自增自减
自增自减会根据位置,决定是先运算还是先输出
--
表示递减操作++
表示递增操作
关系运算符
>
大于,>=
大于等于<
小于,<=
小于等于==
等于===
严格等于!=
表示不等于
1== true // true
5 == true // false
1 === true // false
位运算符
&
按位与运算^
按位异或运算符|
按位或运算符~
按位非运算符
7|11 // 7 按位运算,结果为 15
// 7 转换为二进制是 111 ,11 转换为二进制是 1011
// 0111
// 1011
// 每一位进行 或 运算,得到结果为
// 1111 // 转为十进制为 15
3&2 // 2
7^11
// 7 的二进制为 111,11 的二进制为 1011
// 0111
// 1011
// 1100 这是异或后结果,也就是 12
// 按位非
~5 // -6
// 00000000000000000000000000000101
// 11111111111111111111111111111010
>>
按位进行,向右移动<<
按位进行向左移动,左边超出的位数将会被清除>>>
无符号右移,也称作零填充右移(忽略最开始的符号位)
// >> 右移运算
4 >> 2 // 2
-4 >> 2
// << 左移运算
1<<2 // 4
-1 << 2 // -4
// 无符号右移
const a = 5; // 00000000000000000000000000000101
console.log(a >>> 2); // 00000000000000000000000000000001
// Expected output: 1
const c = -5; // 11111111111111111111111111111011
console.log(c >>> 2); // 00111111111111111111111111111110
// Expected output: 1073741822
注:没有无符号左移
逻辑运算符
基本运算符
- 与运算符
&&
- 或运算符
||
- 非运算符
!
- 空值合并运算符
??
// 与运算符的赋值
const state = true
const content = '这里是一些内容'
const result1 = state && content
const result2 = content && state
// 与运算符也会返回第一个为 false 的内容,如果没有为 false 的内容,返回最后一个
result1 // '这里是一些内容'
result2 // true
// 或运算符的赋值
const result3 = true || '996'
const result4 = false || '996'
运算符的简写
x &&=y
相当于 x && (x=y)
x ||=y
相当于 x || (x=y)
x ??=y
相当于 x ?? (x=y)
let x = 0
x &&=9 // 0
x ||=12 // 12
x ??=55 // 0
空值合并运算符
??
两个问号
用于解决 ||
运算符无法应对的情况,||
中,只要转成 Boolean
后是 false
,左侧的值就会被忽略
let age = 0 || 20
age // 20
let age = '' || null
空值合并预算符只有左侧为 null
或者 undefined
会取右侧的值
let age = 0 ?? 20
age // 0
三步运算符
let x = 10
x>0?x=999:x='wtf'
x // 999
x = x>0?-x:x
x // -999
逗号运算符
会对每个操作数从左到右求值,并返回最后一个操作数的值。
let foo = (2, 3);
foo // 3
// 在三步运算符中指定操作,和返回值时使用
let list = [99,66,88]
let newlist = list.indexOf(70) == -1 ? ( list.push( v ), list ) : list
括号运算符
let x = ( 2 + 20 ) * 20
// 440
可选链操作符
ES2020 中新增的特性
obj.name?.
let obj = {
name:{
firstName:'zhang'
}
}
obj.name.firstName // 一般是这样取值,但是如果不存在 name 无法取值并且报错
// 为了防止报错通常采用以下两种方法
// 1. 使用 if 进行判断
if(obj){
if(obj.name){
let name1 = obj.name.firstName
}
}
// 2.利用 && 运算符的特性
let name2 = obj && obj.name && obj.firstName
// 用了该符号,一次性解决
let name3 = obj?.name?.firstName
操作符关键字
delete
const Employee = {
firstname: 'John',
lastname: 'Doe'
};
console.log(Employee.firstname);
// Expected output: "John"
delete Employee.firstname;
// delete Employee['firstname']
console.log(Employee.firstname);
// Expected output: undefined
in
可以使用 for...in 对对象进行遍历
let obj = {
name:'fall',
age:24
}
// msg 为 obj 的 name、age
for(let msg in obj){
console.log(msg)
}
console.log('name' in obj) // true
new
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A { constructor() { super(); } }
var a = new A(); // logs "A"
var b = new B(); // logs "B"
class C { constructor() { console.log(new.target); } }
class D extends C { constructor() { super(); } }
var c = new C(); // logs class C{constructor(){console.log(new.target);}}
var d = new D(); // logs class D extends C{constructor(){super();}}
instanceof
用于判断某个类是不是另一个类继承的
Array instanceof Object
// true
typeof
用于判断数据的类型
typeof 2 // 'number'
typeof 'fall' // 'string'
typeof false // 'boolean'
typeof [] // 'object'
super
待补充
数值分隔符
_
可以将数字分割,进行声明,方便查看,可以用于多种进制
注:两侧必须都要有数值
let num = 3146_46446
let num1 = 31_n // error 错误书写格式
let num2 = 0x_664 // error 错误书写格式
展开运算符
Spread syntax,可以进行扩展
Math.max(...[1,2,3]) // 3
对象中的应用
可以应用在解构赋值,但是只能应用在最后一个变量上,被接受的值会直接赋值过去,没被接受的会全部复制到展开运算符后的声明数中
let {fall, ...y} = {dear:'55',fall:'23',b:'2',c:3}
y // {b:'2',c:3}
实现对象的合并
let a = {name:'fall'}
let b = {age:'23'}
let info = {...a,...b}
info //{ name: "fall", age: "23" }
数组中的应用
数组的解构赋值
let [a, b, c = 'c'] = '12'
console.log(a, b, c) // '1' '2' 'c'
解构
解构数组
// 结构数组的声明
var [x,y,z] = [10,22,33]
console.log(x+'----'+z )
var [x,y,[a,b],z] =[11,22,[],33]
// 结构函数的声明
var {toFixed:ss} = 1000
// 实际上 此时 ss === Number.prototype.toFixed
解构对象
const {age} = {name:'fall',age:21}
age // 21
// 解构对象上的方法
// 获取到 10 上的 toFixed 方法,并将该方法赋给 tf,任意数值都可以通过解构获取到原型对象上的方法
let {toFixed: tf} = 10
tf.call(Math.PI, 2) // 3.14 // 使用 call 改变指针指向,call 方法读取的是 this 来执行的
解构名称转换
const {a:megic} = {a:'close your eyes'}
megic // 'close your eyes'
解构默认赋值
const {a=10,b=100} = {a:36}
解构的用途
// 1. 交换变量的值
var [a,b] = [11,22];
[a,b] = [b,a];
alert(a+' and '+b);
// 2. 可以返回多个变量的值
function etc(){
return ['acj','txt','fbi'];
}
var [r1,r2,r3] =etc()
// 3.解决必须通过固定格式书写的问题
// 参数可以传入默认值
// 固定格式书写
function file(name,age,gender){
alert('我叫'+name+',今年'+age+'岁,性别是'+gender);
}
file('小明',55,'男');
// 非固定格式书写
function file({name,age,gender = 'boy'}){
alert('我叫'+name+',今年'+age+'岁,性别是'+gender);
};
file({
name:'小明',
gender:'男',
age:22,
})
// 注,至少传入一个对象才能成功地调用方法
file({})
// 4.快速取出数组
var arr = [11,22,33,44,55];
var {0:first,4:last} = arr;
alert(first);
alert(last == arr[4]);
获取数据类型上的方法
let {toFixed: tf} = 10
// 获取到 10 上的 toFixed 方法,并将该方法赋给 tf
console.log(tf.call(Math.PI, 2)) // 3.14
布尔值解构
let {toString: ts} = true
console.log(ts.call(false)) // 'false'
数组解构:等号右侧的数据具有 Iterator
接口可以进行数组形式的解构赋值;
// 解构不成功的变量值为 undefined
let [a, b, c] = [1, 2]
console.log(a, b, c) // 1, 2, undefined
// 可以设置默认值
let [x, y, z = 3] = [1, 2, null]
console.log(x, y, z) // 1, 2, null
什么样的数据具有
Iterator
接口呢?如果一个对象能够通过 [Symbol.iterator] 访问,且能够返回一个符合迭代器协议的对象,那么该对象就是可迭代的。目前内置的可迭代对象有:String、Array、TypeArray、Map、Set、arguments 和 NodeList 等。
- 对象解构:与数组按照索引位置进行解构不同,对象解构是按照属性名进行解构赋值,如果在当前对象属性匹配不成功则会去对象的原型属性上查找:
// 默认写法
let { name: name, age: age } = { name: '布兰', age: 12 }
// 简写
let { name, age } = { name: '布兰', age: 12 }
// 改名且设置默认值
let { name: name1, age: age1 = 12 } = { name: '布兰' }
console.log(name1, age1) // '布兰' 12
-
函数参数解构:其实就是运用上面的对象解构和数组解构规则;
function move({x = 0, y = 0} = {}) {
console.log([x, y])
return [x, y];
}
move({x: 3, y: 8}) // [3, 8]
move({x: 3}) // [3, 0]
move({}) // [0, 0]
move() // [0, 0]
解构要点:
- 只要等号两边的模式相同(同是对象或同是数组),则左边的变量会被赋予对应的值;
- 解构不成功的变量值为
undefined
; - 默认值生效的前提是当等号右边对应的值全等于 undefined 的时候;
- 只要等号右边的值不是对象或者数组,则会进行自动装箱将其转成对象;
null
和undefined
都无法转成对象,所以无法解构。
解构应用:
-
交换变量的值;
let x = 1, y = 2;
// 交换时,不要对 x、y 的值进行操作
[x, y] = [y, x]
console.log(x, y) // 2 1 -
通过函数返回对象属性
function getParams() {
return {
name: '布兰',
age: 12,
}
}
let {name, age} = getParams() -
通过定义函数参数来声明变量
let person = {
name: '布兰',
age: 12
}
init(person)
// 普通用法
function init(person) {
let {name, age} = person
}
// 更简洁用法
function init({name, age}) {} -
指定函数参数默认值
function initPerson({name = '布兰', age = 12} = {}) {
console.log(name, age)
}
initPerson() // '布兰' 12
initPerson({age: 20}) // '布兰' 20 -
提取
JSON
数据let responseData = {
code: 1000,
data: {msg:'来了来了'},
message: 'success'
}
// 这里面的 data 为默认值
let { code, data = {} } = responseData -
遍历 Map 结构
let map = new Map()
map.set('beijing', '北京')
map.set('xiamen', '厦门')
for (let [key, value] of map) {
console.log(key, value)
} -
输入模块的指定方法和属性
const { readFile, writeFile } = require("fs")
参考文章
文章名称 | 链接 |
---|---|
「建议收藏」送你一份精心总结的3万字ES6实用指南(上) | https://juejin.cn/post/6895898051559456776#heading-6 |
MDN 官方文档 | https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators |